package org.theonept.travian.t4a.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.theonept.travian.dao.CompteDAO;
import org.theonept.travian.dao.DatabaseHelper;
import org.theonept.travian.model.Compte;
import org.theonept.travian.model.Message;
import org.theonept.travian.model.Village;
import org.theonept.travian.t4a.MainActivity;
import org.theonept.travian.t4a.R;
import org.theonept.travian.t4a.village.VillageActivity;
import org.theonept.travian.util.AsyncWeb;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.Log;

public class Travian4AndoidService extends Service {
	private static boolean running = false;
	public static final int ID_MESSAGE_NOTIFICATION = 32000;
	public static final int ID_ATTACK_NOTIFICATION = 64000;
	public static final Map<Integer, Set<Long>> mapIdMessage = new HashMap<Integer, Set<Long>>();

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		int res = super.onStartCommand(intent, flags, startId);
		setRunning(true);
		DatabaseHelper.getInstance(getApplicationContext());
		new CompteAsync(null).execute();
		return res;
	}

	private void scheduleNextUpdate() {

		// The update frequency should often be user configurable. This is not.
		SharedPreferences preftime = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		;

		int syncMinute = Integer.valueOf(preftime.getString("prefNotifSyncFrequency", "10"));
		if (syncMinute > 0) {
			Intent intent = new Intent(this, this.getClass());
			PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
			long currentTimeMillis = System.currentTimeMillis();
			long nextUpdateTimeMillis = currentTimeMillis + syncMinute * DateUtils.MINUTE_IN_MILLIS;
			Time nextUpdateTime = new Time();
			nextUpdateTime.set(nextUpdateTimeMillis);

			AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
			alarmManager.set(AlarmManager.RTC, nextUpdateTimeMillis, pendingIntent);
		}

	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		setRunning(false);
	}

	/**
	 * @return the running
	 */
	public static boolean isRunning() {
		return running;
	}

	/**
	 * @param running
	 *            the running to set
	 */
	public static void setRunning(boolean running) {
		Travian4AndoidService.running = running;
	}

	class CompteAsync extends AsyncWeb<Compte, Void, Boolean> {

		public CompteAsync(Compte compte) {
			super(compte);
			// TODO Auto-generated constructor stub
		}

		@Override
		protected void onPostExecute(Boolean result) {

			scheduleNextUpdate();
			super.onPostExecute(result);
		}

		@Override
		protected Boolean executeWebTask(Compte... params) {

			SharedPreferences preftime = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

			int syncMinute = Integer.valueOf(preftime.getString("prefNotifSyncFrequency", "10"));
			if (syncMinute > 0) {
				NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

				List<Compte> comptes = CompteDAO.getINSTANCE().queryForAll();
				for (Compte compte : comptes) {
					try {

						if (compte.isEtat(true, true)) {

							if (preftime.getBoolean("prefNotifMessage", true)) {
								messageNotification(mNotificationManager, compte);

							}

							if (preftime.getBoolean("prefNotifVillageUnderAttack", true)) {
								attaqueNotification(mNotificationManager, compte);
							}
						}
					} catch (Exception e) {
						if (e != null && e.getMessage() != null) {
							Log.e("", e.getMessage());
						}
					}
				}

			}

			return true;
		}

		private void messageNotification(NotificationManager mNotificationManager, Compte compte) {
			Notification notifMessage = null;
			int id = (int) (ID_MESSAGE_NOTIFICATION * compte.getIdCompte());
			List<Message> messages = compte.getUnreadMessage();
			if (!Travian4AndoidService.mapIdMessage.containsKey(id)) {
				Travian4AndoidService.mapIdMessage.put(id, new HashSet<Long>());

			}

			if (messages.size() == 1) {
				Message message = messages.get(0);
				if (!mapIdMessage.containsKey(id)
						|| (mapIdMessage.containsKey(id) && !mapIdMessage.get(id).contains(message.getId()))) {
					Intent intent = new Intent(getApplicationContext(), MainActivity.class);

					intent.putExtra("message", message);
					intent.putExtra("compte_id", compte.getIdCompte());
					intent.putExtra("mode", "message");

					Travian4AndoidService.mapIdMessage.get(id).add(message.getId());

					PendingIntent resultPendingIntent = PendingIntent
							.getActivity(getApplicationContext(), 0, intent, 0);

					notifMessage = new Notification.Builder(getApplicationContext())
							.setOnlyAlertOnce(true)
							.setContentTitle(getResources().getString(R.string.message) + getTextfromUrl(compte))
							.setContentText(
									getResources().getString(R.string.read_from) + " " + message.getExpediteur() + " "
											+ getResources().getString(R.string.read_subject) + message.getSujet())
							.setSmallIcon(R.drawable.ic_launcher).setContentIntent(resultPendingIntent)
							.setAutoCancel(true).setWhen(message.getDate().getTime()).getNotification();
				}
			} else if (messages.size() > 1) {
				boolean showNotification = false;
				if (mapIdMessage.containsKey(id)) {
					Set<Long> longs = mapIdMessage.get(id);
					for (Message message : messages) {
						if (!longs.contains(message.getId())) {
							showNotification = true;
							break;

						}
					}
				} else {
					showNotification = true;
				}
				if (showNotification) {

					Intent intent = new Intent(getApplicationContext(), MainActivity.class);
					intent.putExtra("compte_id", compte.getIdCompte());
					intent.putExtra("mode", "message");
					ArrayList<Long> longs = new ArrayList<Long>();
					for (Message message : messages) {
						longs.add(message.getId());
					}
					Travian4AndoidService.mapIdMessage.get(id).addAll(longs);
					PendingIntent resultPendingIntent = PendingIntent
							.getActivity(getApplicationContext(), 0, intent, 1);

					notifMessage = new Notification.Builder(getApplicationContext())
							.setOnlyAlertOnce(true)
							.setContentTitle(getResources().getString(R.string.messages) + " " + getTextfromUrl(compte))
							.setContentText(messages.size() + " " + getResources().getString(R.string.new_messages))
							.setSmallIcon(R.drawable.ic_launcher).setAutoCancel(true)

							.setContentIntent(resultPendingIntent).getNotification();
				}

			} else {
				mNotificationManager.cancel(id);
			}
			if (notifMessage != null) {
				notifMessage.defaults |= Notification.DEFAULT_SOUND;
				notifMessage.defaults |= Notification.DEFAULT_VIBRATE;
				mNotificationManager.notify(id, notifMessage);

			}
		}

	}

	private String getTextfromUrl(Compte compte) {
		return compte.getUrlServeur().replace("http://", "").replace("/", "");
	}

	public void attaqueNotification(NotificationManager mNotificationManager, Compte compte) {

		int id = (int) (ID_MESSAGE_NOTIFICATION * compte.getIdCompte());

		for (Village village : compte.getVillages()) {
			village.getProduction();
			if (village.getNbUnderAttack() > 0) {
				Intent intent = new Intent(getApplicationContext(), VillageActivity.class);
				intent.putExtra("compte", compte);
				intent.putExtra("village", village);

				PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 1);
				Notification notifAttack = new Notification.Builder(getApplicationContext())
						.setContentTitle(getTextfromUrl(compte))
						.setOnlyAlertOnce(true)
						.setContentText(
								getResources().getString(R.string.your_village) + " " + village.getNomVillage() + " "
										+ getResources().getString(R.string.is_under_attack))
						.setContentIntent(resultPendingIntent).setSmallIcon(R.drawable.ic_launcher).getNotification();
				notifAttack.defaults |= Notification.DEFAULT_SOUND;
				notifAttack.defaults |= Notification.DEFAULT_VIBRATE;
				mNotificationManager.notify(ID_ATTACK_NOTIFICATION * Integer.valueOf(village.getIdVillage()),
						notifAttack);
			} else {
				mNotificationManager.cancel(ID_ATTACK_NOTIFICATION * Integer.valueOf(village.getIdVillage()));
			}
		}

	}

}
